export * from "./md";
import { formatDate, isArr, isNumber, isObj, isStringT } from "./md";

export type ImplFromat = { [k in gt.gl.SqlK]: (p?: any) => Promise<gt.gl.SqlT<k>>; };
export class BaseFormat {
  //#region 基础内容
  protected isPages(p: any): p is gt.PageData<any> {
    if (p && isNumber(p.current) && isNumber(p.total) && isNumber(p.size)) {
      if (isArr(p.data)) {
        return true;
      } else if (isArr(p.records)) {
        Object.assign(p, {
          current: parseInt(p.current),
          total: parseInt(p.total),
          size: parseInt(p.size),
          data: p.records,
        });
        delete p.records;
        return true;
      }
    }
    return false;
  }
  async setDef<T extends obj>(dist: obj, def: T) {
    for (const k in def) {
      dist[k] = dist[k] || def[k];
      if (k === "create" && dist[k] && !dist[`_create`]) {
        dist[`_create`] = { name: "-" };
        await this.setEntity(dist, "user", k);
      }
    }
    return dist as T;
  }
  async setEntity<T extends obj, RK extends gt.gl.SqlK>(p: T, SqlK: RK, pk: Array<Key<T>>): Promise<gt.gl.SqlT<RK>>;
  async setEntity<T extends obj, RK extends gt.gl.SqlK>(p: T, SqlK: RK, pk: Key<T>, rp?: string): Promise<gt.gl.SqlT<RK>>;
  async setEntity<T extends obj, RK extends gt.gl.SqlK>(p: T, SqlK: RK, pk: string, rp?: string): Promise<gt.gl.SqlT<RK>>;
  async setEntity<T extends obj, RK extends gt.gl.SqlK>(p: T, SqlK: RK, pk: Key<T> | Array<Key<T>>, rp?: string): Promise<gt.gl.SqlT<RK>> {
    if (isObj(p) && this.gd[SqlK] && pk) {
      if (isStringT(pk) && p[pk]) {
        if (!rp) { rp = "_" + pk; }
        const d = await this.gd[SqlK].getById(p[pk]);
        // @ts-ignore
        p[rp] = d || this.def[SqlK];
      } else if (Array.isArray(pk)) {
        for (const k of pk) {
          await this.setEntity(p, SqlK, k);
        }
      }
    }
    return p as any as gt.gl.SqlT<RK>;
  }
  setTime(p: obj, key?: string) {
    if (key) {
      p[key] = parseInt(p[key]);
      p[`_${key}`] = formatDate(p[key]);
    } else {
      Object.keys(p).forEach(k => {
        if (/time/ig.test(k) && isNumber(p[k])) {
          p[k] = parseInt(p[k]);
          p[`_${k}`] = formatDate(p[k]);
        }
      });
    }
  }
  readonly def: gt.gl.Def;
  readonly gd: gt.gl.Gd = null as any;
  constructor (def: gt.gl.Def) {
    this.def = def;
  }
  setGd(gd: gt.gl.Gd) {
    // @ts-ignore
    this.gd = gd;
  }
  //#endregion 基础内容
  // #region 格式化主体
  // async addr(p?: any): Promise<any> {
  //   if (Array.isArray(p)) {
  //     await Promise.all(p.map(async (v) => { await this.addr(v); }));
  //     return p;
  //   } else if (this.isPages(p)) {
  //     await this.addr(p.data);
  //     return p;
  //   } else if (p) {
  //     this.setDef(p, def.addr);

  //     return p;
  //   }
  // };
  // #endregion 格式化主体
}
